using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SeataNet.Core.Configuration;
using System.Reflection;

namespace SeataNet.Core.TCC
{
    /// <summary>
    /// TCC模式服务集合扩展
    /// </summary>
    public static class TccServiceCollectionExtensions
    {
        /// <summary>
        /// 添加TCC模式服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccMode(this IServiceCollection services)
        {
            return services.AddTccMode(null);
        }

        /// <summary>
        /// 添加TCC模式服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configure">配置选项</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccMode(this IServiceCollection services, Action<TccConfiguration> configure)
        {
            // 添加配置
            if (configure != null)
            {
                services.Configure(configure);
            }
            else
            {
                services.Configure<TccConfiguration>(options => { });
            }

            // 添加TCC核心服务
            services.AddSingleton<ITccTransactionManager, DefaultTccTransactionManager>();
            services.AddSingleton<ITccServiceRegistry, DefaultTccServiceRegistry>();
            services.AddSingleton<TccServiceFactory>();
            services.AddSingleton<TccTransactionAspect>();
            services.AddSingleton<TccTransactionTemplate>();

            // 注册TCC方法拦截器
            services.AddTransient<TccMethodInterceptor>();

            // 添加TCC配置验证
            services.AddSingleton<IValidateOptions<TccConfiguration>, TccConfigurationValidator>();

            return services;
        }

        /// <summary>
        /// 添加TCC服务
        /// </summary>
        /// <typeparam name="TService">服务接口类型</typeparam>
        /// <typeparam name="TImplementation">服务实现类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="serviceName">服务名称</param>
        /// <param name="isLocalService">是否是本地服务</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService<TService, TImplementation>(
            this IServiceCollection services,
            string? serviceName = null,
            bool isLocalService = true)
            where TService : class
            where TImplementation : class, TService
        {
            // 注册服务实现
            services.AddTransient<TService, TImplementation>();

            // 注册TCC服务工厂
            services.AddSingleton(provider =>
            {
                var factory = provider.GetRequiredService<TccServiceFactory>();
                return factory.CreateService<TService>(serviceName, isLocalService);
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务
        /// </summary>
        /// <typeparam name="TService">服务接口类型</typeparam>
        /// <typeparam name="TImplementation">服务实现类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">TCC服务配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService<TService, TImplementation>(
            this IServiceCollection services,
            TccServiceConfiguration configuration)
            where TService : class
            where TImplementation : class, TService
        {
            // 注册服务实现
            services.AddTransient<TService, TImplementation>();

            // 注册TCC服务工厂
            services.AddSingleton(provider =>
            {
                var factory = provider.GetRequiredService<TccServiceFactory>();
                return factory.CreateService<TService>(configuration);
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务（仅接口）
        /// </summary>
        /// <typeparam name="TService">服务接口类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="serviceName">服务名称</param>
        /// <param name="isLocalService">是否是本地服务</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService<TService>(
            this IServiceCollection services,
            string? serviceName = null,
            bool isLocalService = true)
            where TService : class
        {
            // 注册TCC服务工厂
            services.AddSingleton(provider =>
            {
                var factory = provider.GetRequiredService<TccServiceFactory>();
                return factory.CreateService<TService>(serviceName, isLocalService);
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务（使用Type参数，用于反射场景）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="serviceType">服务类型</param>
        /// <param name="serviceName">服务名称</param>
        /// <param name="isLocalService">是否是本地服务</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService(
            this IServiceCollection services,
            Type serviceType,
            string? serviceName = null,
            bool isLocalService = true)
        {
            // 注册服务实现
            services.AddTransient(serviceType);

            // 注册到TCC服务注册表
            services.AddSingleton(provider =>
            {
                var registry = provider.GetRequiredService<ITccServiceRegistry>();
                var serviceInstance = provider.GetRequiredService(serviceType);
                registry.RegisterService(serviceType, serviceInstance);
                return serviceInstance;
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务（使用Type参数，指定接口和实现）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="interfaceType">服务接口类型</param>
        /// <param name="implementationType">服务实现类型</param>
        /// <param name="serviceName">服务名称</param>
        /// <param name="isLocalService">是否是本地服务</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService(
            this IServiceCollection services,
            Type interfaceType,
            Type implementationType,
            string? serviceName = null,
            bool isLocalService = true)
        {
            // 注册服务实现
            services.AddTransient(interfaceType, implementationType);

            // 注册到TCC服务注册表
            services.AddSingleton(provider =>
            {
                var registry = provider.GetRequiredService<ITccServiceRegistry>();
                var serviceInstance = provider.GetRequiredService(interfaceType);
                registry.RegisterService(interfaceType, serviceInstance);
                return serviceInstance;
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务（仅接口）
        /// </summary>
        /// <typeparam name="TService">服务接口类型</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">TCC服务配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccService<TService>(
            this IServiceCollection services,
            TccServiceConfiguration configuration)
            where TService : class
        {
            // 注册TCC服务工厂
            services.AddSingleton(provider =>
            {
                var factory = provider.GetRequiredService<TccServiceFactory>();
                return factory.CreateService<TService>(configuration);
            });

            return services;
        }

        /// <summary>
        /// 添加TCC服务（自动扫描）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="assemblies">程序集列表</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddTccServicesFromAssembly(
            this IServiceCollection services,
            params Assembly[] assemblies)
        {
            if (assemblies == null || assemblies.Length == 0)
            {
                assemblies = new[] { Assembly.GetCallingAssembly() };
            }

            foreach (var assembly in assemblies)
            {
                // 查找所有带有TccServiceAttribute的类
                var serviceTypes = assembly.GetTypes()
                    .Where(t => t.IsClass && !t.IsAbstract && t.GetCustomAttribute<TccServiceAttribute>() != null)
                    .ToList();

                foreach (var serviceType in serviceTypes)
                {
                    var attribute = serviceType.GetCustomAttribute<TccServiceAttribute>();
                    
                    // 查找实现的接口
                    var interfaces = serviceType.GetInterfaces().ToList();
                    
                    if (interfaces.Count == 0)
                    {
                        // 如果没有实现接口，则直接注册类
                        services.AddTccService(serviceType, attribute.ServiceName, attribute.IsLocalService);
                    }
                    else
                    {
                        // 为每个接口注册服务
                        foreach (var interfaceType in interfaces)
                        {
                            services.AddTccService(interfaceType, serviceType, attribute.ServiceName, attribute.IsLocalService);
                        }
                    }
                }
            }

            return services;
        }
    }

    /// <summary>
    /// TCC模式配置
    /// </summary>
    public class TccConfiguration
    {
        /// <summary>
        /// 默认超时时间（毫秒）
        /// </summary>
        public int DefaultTimeoutMs { get; set; } = 60000;

        /// <summary>
        /// 默认重试次数
        /// </summary>
        public int DefaultRetryCount { get; set; } = 3;

        /// <summary>
        /// Try方法后缀
        /// </summary>
        public string TryMethodSuffix { get; set; } = "Try";

        /// <summary>
        /// Confirm方法后缀
        /// </summary>
        public string ConfirmMethodSuffix { get; set; } = "Confirm";

        /// <summary>
        /// Cancel方法后缀
        /// </summary>
        public string CancelMethodSuffix { get; set; } = "Cancel";

        /// <summary>
        /// 是否启用异步处理
        /// </summary>
        public bool EnableAsyncProcessing { get; set; } = true;

        /// <summary>
        /// 是否启用自动注册
        /// </summary>
        public bool EnableAutoRegistration { get; set; } = true;

        /// <summary>
        /// 服务发现配置
        /// </summary>
        public ServiceDiscoveryConfiguration ServiceDiscovery { get; set; } = new ServiceDiscoveryConfiguration();

        /// <summary>
        /// 负载均衡配置
        /// </summary>
        public LoadBalancingConfiguration LoadBalancing { get; set; } = new LoadBalancingConfiguration();
    }

    /// <summary>
    /// 服务发现配置
    /// </summary>
    public class ServiceDiscoveryConfiguration
    {
        /// <summary>
        /// 服务发现类型
        /// </summary>
        public string Type { get; set; } = "Consul";

        /// <summary>
        /// 服务发现地址
        /// </summary>
        public string Address { get; set; } = "localhost:8500";

        /// <summary>
        /// 健康检查间隔（秒）
        /// </summary>
        public int HealthCheckInterval { get; set; } = 10;

        /// <summary>
        /// 健康检查超时（秒）
        /// </summary>
        public int HealthCheckTimeout { get; set; } = 5;
    }

    /// <summary>
    /// 负载均衡配置
    /// </summary>
    public class LoadBalancingConfiguration
    {
        /// <summary>
        /// 负载均衡策略
        /// </summary>
        public LoadBalancingStrategy Strategy { get; set; } = LoadBalancingStrategy.RoundRobin;

        /// <summary>
        /// 是否启用健康检查
        /// </summary>
        public bool EnableHealthCheck { get; set; } = true;

        /// <summary>
        /// 健康检查间隔（秒）
        /// </summary>
        public int HealthCheckInterval { get; set; } = 30;
    }

    /// <summary>
    /// 负载均衡策略
    /// </summary>
    public enum LoadBalancingStrategy
    {
        /// <summary>
        /// 轮询
        /// </summary>
        RoundRobin,

        /// <summary>
        /// 随机
        /// </summary>
        Random,

        /// <summary>
        /// 最少连接
        /// </summary>
        LeastConnections,

        /// <summary>
        /// 一致性哈希
        /// </summary>
        ConsistentHash
    }

    /// <summary>
    /// TCC配置验证器
    /// </summary>
    public class TccConfigurationValidator : IValidateOptions<TccConfiguration>
    {
        public ValidateOptionsResult Validate(string? name, TccConfiguration options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            
            var failures = new List<string>();

            if (options.DefaultTimeoutMs <= 0)
            {
                failures.Add("DefaultTimeoutMs 必须大于 0");
            }

            if (options.DefaultRetryCount < 0)
            {
                failures.Add("DefaultRetryCount 不能小于 0");
            }

            if (string.IsNullOrWhiteSpace(options.TryMethodSuffix))
            {
                failures.Add("TryMethodSuffix 不能为空");
            }

            if (string.IsNullOrWhiteSpace(options.ConfirmMethodSuffix))
            {
                failures.Add("ConfirmMethodSuffix 不能为空");
            }

            if (string.IsNullOrWhiteSpace(options.CancelMethodSuffix))
            {
                failures.Add("CancelMethodSuffix 不能为空");
            }

            if (options.ServiceDiscovery == null)
            {
                failures.Add("ServiceDiscovery 不能为 null");
            }
            else
            {
                if (string.IsNullOrWhiteSpace(options.ServiceDiscovery.Type))
                {
                    failures.Add("ServiceDiscovery.Type 不能为空");
                }

                if (string.IsNullOrWhiteSpace(options.ServiceDiscovery.Address))
                {
                    failures.Add("ServiceDiscovery.Address 不能为空");
                }

                if (options.ServiceDiscovery.HealthCheckInterval <= 0)
                {
                    failures.Add("ServiceDiscovery.HealthCheckInterval 必须大于 0");
                }

                if (options.ServiceDiscovery.HealthCheckTimeout <= 0)
                {
                    failures.Add("ServiceDiscovery.HealthCheckTimeout 必须大于 0");
                }
            }

            if (options.LoadBalancing == null)
            {
                failures.Add("LoadBalancing 不能为 null");
            }
            else
            {
                if (options.LoadBalancing.HealthCheckInterval <= 0)
                {
                    failures.Add("LoadBalancing.HealthCheckInterval 必须大于 0");
                }
            }

            return failures.Count > 0
                ? ValidateOptionsResult.Fail(failures)
                : ValidateOptionsResult.Success;
        }
    }
}